<?php
$rawBody = (string) file_get_contents('php://input');
if($rawBody){
	$requestData = json_decode($rawBody, true);
	if(is_array($requestData)){
		$_REQUEST = array_merge($_REQUEST, $requestData);
	}
}

if(!isset($_SESSION)){
	$_SESSION = array();
}
include_once ('mapper/baseMapper.php');
includeFolder("service/mapper");

$publicServices = array(
	"test",
	"login",
	"createUser",
	"serviceLogout",
	"updatePosition",
	"associateLicenseUser", 
	"getProfileInfo",
	"updatePersonProfileInfo",
	"updateCompanyProfileInfo",
	"createBroadcastMessage",
	"getActiveBroadcastMessage",
	"getBroadcastMessages",
	"notifyBroadcastMessage",
	"updateGCMRegID",
	"getInterestsList",
	"nbm",
	"cacular_distancia"
);

$privateServices = array();

$serviceMethod = getInput("method", "");

file_put_contents("/tmp/log.txt",$serviceMethod . "\n". json_encode($_REQUEST) . "\n\n", FILE_APPEND);

date_default_timezone_set('America/Argentina/Buenos_Aires');
$request = $_REQUEST;
if (isset($request["method"])){
	unset($request["method"]);	
}

$_SESSION["serviceLogId"] = ServicesLog::log($serviceMethod, $request);

if (in_array($serviceMethod, $publicServices)) {
	$serviceMethod();
} else {
	if (getUserLoggedInId() == 0) {
		response("","",1, langEcho("user:notLogged"));
	}
	if (function_exists($serviceMethod) && $serviceMethod != "" && in_array($serviceMethod, $privateServices)){
		$serviceMethod();
	}else{
		response("","",1, langEcho("service:not:exist"));
	}
}

function response($key="", $object="", $errorNum = 0, $message = ""){
	$return = new stdClass();
	$return->errorNum = $errorNum;
	$return->message = $message;
	$return->payload = null;
	if($key != ""){
		$return->payload = array();
		$return->payload[$key] = $object;
	}else if(!empty($object)){
		$return->payload = $object;
	}
	$serviceLogId = $_SESSION["serviceLogId"];
	if (isset($serviceLogId) && $serviceLogId != 0){
		ServicesLog::logResponse($serviceLogId, json_encode($return));
	}
	echo json_encode($return); //TODO: (fran) lo pongo por ahora despues se ve como lo arreglamos
	exit;
}

function test(){
	response("Success", "yes", 0, langEcho("Successfull test."));
}

function associateLicenseUser(){
	$licenseTypeId = getInput("licenseTypeId", "");

	if ($licenseTypeId === "") {
		response("", "", 1, langEcho("invalidParameters"));
	}

	$user = getUserFromInput();

	$existLicenseType = new LicenseType($licenseTypeId);
	if ($existLicenseType->attributes){
		// obtengo la licencia del usuario o creo una nueva
		if ($user->attributes->licenseId > 0){
			$license = new License($user->attributes->licenseId);
		}else{
			$license = new License();
		}

		$license->attributes->licenseTypeId = $licenseTypeId;

		//calculo el dia que expira la licencia
		$expirationDate = strtotime('+'.$existLicenseType->attributes->duration.' month');
		$license->attributes->expirationDate = date("Y-m-d H:i:s", $expirationDate);

		$license->save(false);

		$user->setLicense($license->attributes->id);

		response("", $license->buildLicenseResponse(), 0, langEcho("user:success:set:license"));
	}else{
		response("", "", 1, langEcho("user:error:license"));
	}
}

function createUser(){
	set_time_limit(10000);
	$userName = getInput("username", "");
	$password = getInput("password", "");
	$gcm_regid = getInput("gcm_regid", null);

	if ($password && $userName){
		$user = new User();
		$exist = new User();
		$exist->getByUsernameFromAll($userName);
		if($exist->attributes){
			response("userId", "0", 1, langEcho("user:userName:duplicate"));
		}else{
			$user->setPassword($password);
			$user->attributes->username = $userName;
			$user->attributes->type = User::$rolePerson;
			/*
			 * Si me pasan por parametro el gcm_regid se lo agrego al usuario
			 */
			if (isset($gcm_regid)){
				$user->attributes->gcm_regid = $gcm_regid;
			}

			if (!$user->save(false, false)){
				response("userId", "0", 1, langEcho("user:not:created"));
			}else{
				if (USEOPENFIRE){
					$openfireAPI = new Openfire();
					$result = $openfireAPI->addUserToOpenfire($userName, $password);
					if (!$result) {
						response("", "", 1,$openfireAPI->getErrorString());
					}
				}
				response("userId", $user->attributes->id, 0, langEcho("user:success:save"));
			}
		}
	}
	else{
		response("", "", 1, langEcho("invalidParameters"));
	}
}

function updatePosition(){
	$getNearUsers = getInput("getNearUsers",false);
	$latitud = getInput("latitud",false);
	$longitud = getInput("longitud",false);
	$username = getInput("username",false);

	if (!$latitud || !$longitud || !$username){
		response("", "", 1, langEcho("invalidParameters"));
	}
	$user = User::getByUserName($username);
	if(!$user->attributes){
		response("", "", 1, langEcho("usernameError"));
	}
	$user->updatePosition($latitud,$longitud);

	/*
	 * Notifico al usuario los mensajes de broadcast que entren en el rango de la nueva posicion
	 * del usuario
	 */
	notifyBroadcastMessage($user);

	if($getNearUsers){
		$nearUsers = $user->getNearUser();
		$nearUsersMapper = new CompleteUserInfoMapper();
		response("", $nearUsersMapper->objectMapper($nearUsers), 0, langEcho("user:success:update:position"));
	}else{
		response("", "", 1, langEcho("user:error:update:position"));
	}
}

function nbm(){
	$username = getInput("username",false);

	$user = User::getByUserName($username);
	
	/*
	 * Notifico al usuario los mensajes de broadcast que entren en el rango de la nueva posicion
	 * del usuario
	 */
	notifyBroadcastMessage($user);
}

function validateUser(){
	$firstname = getInput("first_name","");
	$lastname = getInput("last_name","");
	$email = getInput("email","");
	$username = getInput("username","");
	$password = getInput("password","");
	$status = 0;//OK
	$error = array();

	//firstname, lastname, institute, username, email -> obligatory
	if($firstname == ""){
		$status = 1;
		$error["first_name"] = array("errorText" => langEcho("firstnameIsEmpty"));
	}
	if($lastname == ""){
		$status = 1;
		$error["last_name"] = array("errorText" => langEcho("lastnameIsEmpty"));
	}
	if($email == ""){
		$status = 1;
		$error["email"] = array("errorText" => langEcho("emailIsEmpty"));
	}else{
		if(!is_email($email)){
			//valid email
			$status = 1;
			$error["email"] = array("errorText" => langEcho("messagevalidateemail"));
			$email = "";
		}
	}
	if($username == ""){
		$status = 1;
		$error["username"] = array("errorText" => langEcho("usernameIsEmpty"));
	}

	//email and username must not be registered
	$exist = new User();
	$exist->getByUsernameFromAll($username);

	$duplicateEmail = new User();
	$duplicateEmail->getByEmail($email);
	$emailDuplicate = false;

	if($email != ""){
		if($duplicateEmail->attributes){
			$emailDuplicate = true;
			if(!$exist->attributes){
				$status = 1;
				$error["email"] = array("errorText" => langEcho("user:email:duplicate"));
			}
		}
	}

	if($username != ""){
		if ($exist->attributes){
			if($firstname && $lastname && $email)
			$suggestions = User::suggestUsernames($username, $firstname, $lastname, $email);
			else
			$suggestions = array();

			$status = 1;
			$error["username"] = array("errorText" => langEcho("user:userName:duplicate"), "suggestedUsernames" => $suggestions);
		}
	}

	//validate password
	if(strlen($password) > MAXPASSLENGTH){
		$status = 1;
		$error["password"] = array("errorText" => sprintf(langEcho("maxpasswordLengthError"),MAXPASSLENGTH));
	}else if(strlen($password) < MINPASSLENGTH){
		$status = 1;
		$error["password"] = array("errorText" => sprintf(langEcho("minpasswordLengthError"), MINPASSLENGTH));
	}

	response("errors", $error, $status, langEcho("status_$status"));
}

function getUserData(){
	$userId = getInput("userId", 0);

	if($userId){
		$user = new User($userId);
		$response = $user->buildLoginResponse(true);
		response("", $response, 0, "");
	}else{
		response("", "", 1, langEcho("invalidParameters"));
	}
}

function serviceLogout() {
	logout();
	response("", "", 0, langEcho("user:logout:success"));
}

function getProfileInfo(){
	$username = getInput("username", "");
	if (!$username){
		response("", "", 1, langEcho("invalidParameters"));
	}
	$user = User::getByUserName($username);
	if(!$user->attributes){
		response("", "", 1, langEcho("usernameError"));
	}
	$userId = $user->id();

	if($userId > 0) {
		$profile = Profile::getProfile($userId);
	}
	if($profile->attributes && isset($profile->attributes->id)){
		$profile->avatarUrl = $user->getIconUrl();
		$mapper = new BaseMapper();
		$result = $mapper->objectMapper($profile);
		response("", $result , 0, langEcho("getUerProfile:success"));
	}else{
		response("", "", 1, langEcho("getUserProfile:error"));
	}
}

function updateProfile($userId, $params){
	if (!empty($userId)){
		if(!empty($params["email"]) && !is_email($params["email"])){
			response("", "", 1, langEcho("messagevalidateemail"));
		}
		$user = new User($userId);
		if ($user->updateProfile($params)) {
			$profile = $user->getProfile();
			$profile->avatarUrl = $user->getIconUrl();
			$mapper = new BaseMapper();
			$result = $mapper->objectMapper($profile);
			response("", $result , 0, langEcho("getUserProfile:success"));
			response("", "", 0, langEcho("updateProfile:success"));
		} else {
			response("", "", 1, langEcho("updateProfile:error"));
		}
	} else {
		response("", "", 1, langEcho("invalidParameters"));
	}
}

function updatePersonProfileInfo(){
	$username = getInput("username", "");
	if (!$username){
		response("", "", 1, langEcho("invalidParameters"));
	}
	$userId = User::getByUserName($username)->id();

	$firstName = getInput("firstName", "");
	$lastName = getInput("lastName", "");
	$email = getInput("email", "");
	$interestTags = getInput("interests", "");
	$birthDate = getInput("birthDate", "");
	$gender = getInput("gender", "");
	$image_base64 = getInput("image_base64", "");

	$params = array(
		"firstName" => $firstName,
		"lastName" => $lastName,
		"email" => $email,
		"interest" => $interestTags,
		"birthDate" => $birthDate,
		"gender" => $gender,
		"image_base64" => $image_base64
	);

	updateProfile($userId, $params);
}

function updateCompanyProfileInfo(){
	$username = getInput("username", "");
	if (!$username){
		response("", "", 1, langEcho("invalidParameters"));
	}
	$userId = User::getByUserName($username)->id();

	$name = getInput("firstName", "");
	$email = getInput("email", "");
	$address = getInput("address", "");
	$tags = getInput("tags", "");
	$phone = getInput("phone", "");
	$image_base64 = getInput("image_base64", "");

	$params = array(
		"name" => $name,
		"address" => $address,
		"email" => $email,
		"tags" => $tags,
		"phone" => $phone,
		"image_base64" => $image_base64
	);

	updateProfile($userId, $params);
}

function login(){
	$userName = getInput("username", "");
	$password = getInput("password", "");
	$passwordHash = getInput("passwordHash", "");
	$gcm_regid = getInput("gcm_regid", null);
	if ($userName && ($password || $passwordHash)){
		$result = authenticateUser($userName, $password, $passwordHash);
		if ($result){
			$user = User::getByUserName($userName);
			if (isset($gcm_regid)){
				$user->gcm_regid = $gcm_regid;
				$user->save(false);
			}
			$response = $user->buildLoginResponse();
			response("", $response, 0, langEcho("user:login:success"));
		}
		else{
			response("userId", "0", 1, langEcho("user:login:error"));
		}
	}
	else{
		response("userId", "0", 1, langEcho("invalidParameters"));
	}
}

function createBroadcastMessage(){
	$title = getInput("title", "");
	$text = getInput("text", "");
	$amount = intval(getInput("amount", 0));

	if ($amount <= 0 || $title === ""){
		response("", "", 1, langEcho("invalidParameters"));
	}

	$loggedUser = getUserFromInput();

	if ($loggedUser->type == 2){
		$message = new CompanyMessages();
		$message->companyId = $loggedUser->id;
		$message->title = $title;
		$message->text = $text;
		$message->amount = $amount;
		$message->save(false);


		/*
		 * Notifico a todos los usuarios por si el mensaje que se creo nuevo cae en el rango de alguno
		 */
		notifyBroadcastMessageAllUsers();

		response("", "", 0, langEcho("message:success:create"));
	}else{
		response("", "", 1, langEcho("user:invalid-type"));
	}
}

/*
 * Retorna los mensajes activos del usuario logueado
 * obviamente si el usuario no es de tipo compania no va a tener mensajes
 */
function getActiveBroadcastMessage(){
	$loggedUser = getUserFromInput();
	$cm = new CompanyMessages();
	response("", CompanyMessages::buildMessagesResponseFromObj($cm->getActiveMessages($loggedUser), false), 0, langEcho("success"));
}

/*
 * Retorna todos los mensajes de broadcast notificados al usuario logueado
 */
function getBroadcastMessages(){
	$limit = getInput("limit", null);

	$companyMessages = new CompanyMessages();
	$user = getUserFromInput();
	
	/*
	 * me pasan por parametro la latitud y longitud laburo con esa y se la actualizo al usuario
	 */
	$lat = getInput("latitud", null);
	$long = getInput("longitud", null);
	if (isset($lat) && isset($long)){
		$user->latitud = $lat;
		$user->longitud = $long;
		$user->save();
	}
	
	$messages = $companyMessages->getBroadcastMessages($user, $limit);

	response("", CompanyMessages::buildMessagesResponseFromObj($messages, true), 0, langEcho("message:success:sent"));
}

function updateGCMRegID(){
	$gcm_regid = getInput("gcm_regid", "");

	if ($gcm_regid == ""){
		response("", "", 1, langEcho("invalidParameters"));
	}

	$loggedUser = getUserFromInput();
	$loggedUser->gcm_regid = $gcm_regid;
	$loggedUser->save(false);

	response("", "", 0, langEcho("gcm_regid:success:update"));
}

function getInterestsList(){
	$list = Profile::getInterestsList();
	response("", $list, 0, langEcho("succes"));
}

function cacular_distancia(){
	echo distance(-34.5971973000, -58.4031086000, -34.5975533648, -58.4030331266)*1000;
}
